home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
dskutil
/
colrboot.zip
/
COLRBOOT.A86
< prev
next >
Wrap
Text File
|
1994-10-29
|
35KB
|
1,372 lines
;----------------------------------------------------------------
; COLRBOOT.A86 - Puts a color message on last four sectors of disk
; and rewrites sector so message will display if the disk is booted.
; For A86V371 assembler 28 July 1994
; Revised for text 3 August 1994
; Minor revision 27 October 1994
; This will assemble with A86 VERSION 3.71
; A86 COLRBOOT.A86
; JIM TUCKER 4/635 Brighton Road, Seacliff
; South Australia, AUSTRALIA 5051 Phone: 61 8 377-1175
; jtucker@adam.com.au
;----------------------------------------------------------------
lf equ 10
cr equ 13
eom equ '$'
; BIOS LOADS BOOT SECTOR Entry:
; CS:IP - 0:7C00h
; DL - boot drive
; ES:SI - Ptr to partition table boot entry (if hard disk)
; All other registers undefined
bytes_per_sec equ word ptr [bp+0bh]
sec_per_cluster equ byte ptr [bp+0dh]
reserved_sec equ word ptr [bp+0eh]
number_of_fats equ byte ptr [bp+10h]
root_size equ word ptr [bp+11h]
total_sec equ word ptr [bp+13h]
media_des_byte equ byte ptr [bp+15h]
sec_per_fat equ word ptr [bp+16h]
sec_per_track equ word ptr [bp+18h]
number_of_heads equ word ptr [bp+1ah]
num_hidden_sec equ word ptr [bp+1ch]
total_sec_long equ word ptr [bp+20h]
drive_number equ word ptr [bp+24h]
reserved equ word ptr [bp+25h]
extended_flag equ word ptr [bp+26h]
vol_serial equ word ptr [bp+27h]
vol_name equ word ptr [bp+2bh]
boot_flag equ word ptr [bp+3feh] ;OFFSET+512 for code
reloc_entry equ OFFSET boot_2 - 100h
boot_hard_msg equ 7900h + OFFSET hard_msg
boot_floppy_msg equ 7900h + OFFSET floppy_msg
boot_halt_msg equ 7900h + OFFSET halt_msg
;--------------------------------------------------------------------
; Boot sector code. The existing BPB on the target disk is written here.
; The target disk *must* be DOS formatted to obtain this information.
;--------------------------------------------------------------------
org 100h
ENTRY: jmp signon ;becomes jmp boot_1
BOOT_DATA db 0 ;NZ to prevent UNREG msg
db 63 dup (0) ;leave room for BPB
BOOT_DATAEND = $
BOOT_1: cli
cld
mov ax,7A00h
xor bx,bx
mov ss,bx ;SS:SP = 0:7A00
mov sp,ax
sti
push si
push bp
mov bp,ax ;BP is new location
; This moves all code from 7A00 to 7C00h and jumps to BOOT_2 via RETF
mov ds,bx ;DS = 0
mov es,bx ;ES = 0
mov di,ax ;Move boot code
mov si,7C00h
mov cx,100h
rep movsw
push es ;Push re-entry segment
mov al,reloc_entry ; BOOT2 OFFSET on stack
push ax ; and go there...
retf
; The code is moved and we read the message to location 8000h
; Note MESG_LOC is the cluster number changed by installation for disk
; sizes other than 1.44M. (1.44 last sctr=2879, we use last eight sectors).
BOOT_2: db 0B8h ;mov ax imm16 instruction
MESG_LOC dw 2870 ;changes with disk size
SKIP_MESG: jmp >l1 ;*** NOPPED BY AUTOBOOT
jmp test_hard ; AND NOFILE
L1: call maths ;do disk sums
mov bx,8000h ;where to put it
; This tries to read our message file (five times)
mov si,5
L1: mov dl,0 ;drive zero
mov ax,0208h ;read eight sectors
int 13h
jnc done
xor ax,ax
int 13h
dec si
jnz l1
; Fall thru, if the read failed. We will not have the message code AAAAh
; and the message won't display anyway. Test for AAAAh (our code words)
; and if not found do not display anything. This prevents garbage
; display if the disk has been filled.
DONE: mov si,8000h ;where it is in memry
lodsw ;get first word
cmp ax,0AAAAh ;us?
je >l1 ;yes
jmp test_hard ;no message to write
; This writes the color message direct to the screen
L1: mov ah,0Fh ;get video mode
int 10h
push ax
mov ah,0 ;clear screen
int 10h ; by resetting mode
pop ax
cmp al,3
mov ax,0B800h
jbe >l1
mov ah,0B0h ;(al is already zero)
L1: push es ;get screen segment in es
mov es,ax
xor di,di
push di
pop ds
mov cx,25*80 ;screen size
repnz movsw
pop es
; Note CURPOS can be modified on the command line by /Pnn
db 0B6h ;mov dh imm8 instruction
CURPOS db 21 ;cursor line (Starts at 0)
mov dl,0 ; and column
mov bh,dl ;video page zero
mov ah,2 ;position cursor
int 10h
TEST_HARD: mov ah,10h ;test for hard disk
mov dl,80h ;first disk only
int 13h ;if exist
jc >l4 ;not found
; Note if the following JMP is nopped by installer we boot immediately
; from the hard drive.
BOOT_C: jmp >l9 ;** NOPPED for autoboot
push bp
jmp boot_hard
L9: push bp
mov ah,0
int 1ah
db 81h,0C2h ;add dx imm16 opcode
TIMER_WORD dw 0 ;default = 1/18th secs
inc dx ;in case he makes it zero
; and clocks rolls over
mov bx,dx ; during this op
L2: int 1ah
cmp dx,bx
jne l2
mov si,boot_hard_msg ;wanna boot it?
call bprint_msg
L21: mov ah,1 ;clear kboard buffer
int 16h ; in case he hit keys
jz >l3 ; during time delay
xor ah,ah ;ah=0
int 16h
jmp l21
L3: xor ah,ah ;BIOS get key
int 16h
or al,20h
cmp al,'y'
je boot_hard ;yes
cmp al,'n'
jne l3
; Fall thru to boot from floppy
L4: mov si,boot_floppy_msg ;wants floopy boot
call bprint_msg
mov ah,0 ;wait for a key
int 16h
call clear_screen
int 19h ;warm boot
; This reads drive C: sector zero into 7C00h and jumps there
BOOT_HARD: call clear_screen
pop bp
call boot_read_disk
jc boot_error
cmp boot_flag,0AA55h ;Check for boot sig
jne boot_error
pop bp ;Restore BP from entry
pop si ; Is BP for DR-DOS only?
jmp bx ;Jump to new boot rec
;Clear the screen
CLEAR_SCREEN: mov ah,0Fh ;get video mode
int 10h
mov ah,0 ;set video mode
int 10h
ret
BOOT_ERROR: mov si,boot_halt_msg ;Print err message
BOOT_ERROR1: call bprint_msg
BOOT_HALT: jmp boot_halt ;STOP!
;-----------------------------------------------------------------------
; BOOT_READ_DISK: Reads one sector from the hard disk
; CF - Clear if read successful.
;-----------------------------------------------------------------------
BOOT_READ_DISK: xor ax,ax ;Read boot sector
call maths
mov bx,7C00h ;where to put it
L1: mov dl,80H ;80h is first hard disk
mov ax,0201h ;read one sector
int 13h
jnc ret ;no error, exit
xor ax,ax ;reset disk before reading
int 13h
dec si
jnz l1
mov si,boot_halt_msg ;read error message
stc
ret
; This does some calculations common to both disk reads
MATHS: cwd
div sec_per_track
inc dx
mov bx,dx
cwd
div number_of_heads
xchg ah,al
mov cl,6
shl al,cl
xchg cx,ax
or cl,bl
mov dh,dl
mov si,5
ret
;--------------------------------------------------------------------
; BPRINT_MSG: - Prints a message to the screen
; Entry: DS:SI - Points to ASCIIZ message
;--------------------------------------------------------------------
BPRINT_MSG: push bx
push bp
L1: lodsb
or al,al
je >l2
mov ah,0eh
mov bx,7h
push si
int 10h
pop si
jmp l1
L2: pop bp
pop bx
ret
HALT_MSG db 'CANNOT BOOT - SYSTEM HALTED ',0
FLOPPY_MSG db cr,lf
db 'Non-System disk. Replace and ',cr,lf
db 'press any key when ready ',0
HARD_MSG db 'Boot from hard disk (Y/N)? ',0
BOOTCODE_END = $
SPARE_DATA = 2FEh-BOOTCODE_END
db spare_data dup ' '
org 2FEh
dw 0AA55h
;****************************************************************
; START OF INSTALLATION CODE
;****************************************************************
IBM_SYS db 'A:IBMBIO.COM',0
MS_SYS db 'A:IO.SYS',0
AUTOBOOT db 'AUTOBOOT',0
NOFILE db 'NOFILE',0
BLANK db 'BLANK',0
TARGET_DISK db 0
REGISTER_BYTE db ?
VIDEO_SEG dw 0B800h
OLD_VIDEO_SEG dw 0B800h
MONO_SWITCH db 0
VIDEO_MODE db ?
SIGNON: mov dx,OFFSET hello
mov ah,9
int 21h
call clear_buffers ;intialise to zero
call cmdline ;sort it out
call check_register ;/R to prevent display
call check_video ;/M for mono?
call check_curpos ;see if cursor positioned
call check_timer ;see if timer set
call check_color ;see if color for text
call check_filename ;want it displayed?
call read_file1 ;check the filename etc
call read_file2 ;read text file if any
call get_target ;handle A: or B:
call check_sys ;ensure not a system disk
call get_size ;how big is it?
call verify ;check sectors are free
call write_message ;write our message
call write_boot ;write the boot sector
mov dx,OFFSET done_message
mov ah,9
int 21h
mov ax,4C00h
int 21h
;----------------------------------------------------------------
; Clears buffers to zero bytes
;----------------------------------------------------------------
CLEAR_BUFFERS: mov di,TEXT_FILE_BUFFER
mov ax,0
mov cx,1000
rep stosw
mov ah,[103h]
mov register_byte,ah
ret
;----------------------------------------------------------------
; Check registered
;----------------------------------------------------------------
CHECK_REGISTER: mov si,OFFSET switch_buffer
L2: lodsb
L3: or al,al ;end
jz ret ;yes
cmp al,'/' ;switch
jne l2 ;no
lodsb ;get
cmp al,'R' ;us?
jne l3 ;no, maybe zero
mov register_byte,1 ;set reg byte
ret
;----------------------------------------------------------------
; CHECK_VIDEO: This checks if user wants mono display
;----------------------------------------------------------------
CHECK_VIDEO: mov ah,0Fh ;get current mode
int 10h ;video
mov video_mode,al ;save current mode
cmp al,7 ;is it mono?
jne >l1 ;no
mov ax,0B000h
mov video_seg,ax ;change seg
mov old_video_seg,ax
L1: mov si,OFFSET switch_buffer
L2: lodsb
L3: or al,al ;end
jz ret ;yes
cmp al,'/' ;switch
jne l2 ;no
lodsb ;get
cmp al,'M' ;us?
jne l3 ;no, maybe zero
mov mono_switch,1 ;set mono switch
ret
;----------------------------------------------------------------
; CHECK_CURPOS: This checks for optional cursor position /Pnn
;----------------------------------------------------------------
TEN dw 10
CHECK_CURPOS: mov si,OFFSET switch_buffer
L1: lodsb ;get
L2: or al,al ;done?
jz ret ;yes
cmp al,'/' ;switch?
jne l1 ;no
lodsb ;get
cmp al,'P' ;us?
jne l2 ;no, maybe zero
mov al,[si] ;get next
or al,al ;zero
jz bad_curpos ;error
cmp al,'=' ;=?
jne >l2 ;no, assume digit
inc si ;scrub it
L2: xor ax,ax ;arithmetic
xor bx,bx
xor dx,dx
L3: mov bl,[si]
or bl,bl
jz >l4
cmp bl,'/'
je >l4
inc si
sub bl,'0'
jc bad_curpos
cmp bl,9
ja bad_curpos
mul ten
add ax,bx
jmp l3
L4: dec al
mov curpos,al
ret
BAD_CURPOS: mov dx,OFFSET bad_curpos_mesg
jmp error_message
;----------------------------------------------------------------
; CHECK_TIMER: This checks for optional time out /Tnn
;----------------------------------------------------------------
TICKS_PER_SEC dw 18
CHECK_TIMER: mov si,OFFSET switch_buffer
L1: lodsb ;get
L2: or al,al ;done?
jz ret ;yes
cmp al,'/' ;switch?
jne l1 ;no
lodsb ;get
cmp al,'T' ;us?
jne l2 ;no, maybe zero
mov al,[si] ;get next
or al,al ;zero
jz bad_timer ;error
cmp al,'=' ;=?
jne >l2 ;no, assume digit
inc si ;scrub it
L2: xor ax,ax ;arithmetic
xor bx,bx
xor dx,dx
L3: mov bl,[si]
or bl,bl
jz >l4
cmp bl,'/'
je >l4
inc si
sub bl,'0'
jc bad_timer
cmp bl,9
ja bad_timer
mul ten
add ax,bx
jmp l3
L4: cmp ax,60
jbe >l5
mov dx,OFFSET too_long_mesg
jmp error_message
L5: mul ticks_per_sec
mov timer_word,ax
ret
BAD_TIMER: mov dx,OFFSET bad_timer_mesg
jmp error_message
;----------------------------------------------------------------
; CHECK_COLOR: This tests for option text color in hex
;----------------------------------------------------------------
SIXTEEN dw 16
CHECK_COLOR: mov si,OFFSET switch_buffer
L1: lodsb ;get char
L2: or al,al ;end?
jz ret ;yes
cmp al,'/' ;switch?
jne l1 ;no
lodsb ;get next
cmp al,'C' ;us?
jne l2 ;no
mov al,[si] ;next
or al,al ;end?
jz show_colors ;yes
cmp al,'=' ;this?
jne >l2 ;no, assume digit
inc si ;lose it
L2: xor ax,ax ;arithmetic
xor bx,bx
xor dx,dx
L3: mov bl,[si]
or bl,bl
je >l5
cmp bl,'/'
je >l5
inc si
xchg ax,bx
call caps
xchg bx,ax
sub bl,'0'
jc show_colors
cmp bl,9
jbe >l4
sub bl,7
jc show_colors
cmp bl,15
ja show_colors
L4: mul sixteen
add ax,bx
jmp l3
L5: or ax,ax
jz show_colors
or dx,dx
jnz show_colors
or ah,ah
jnz show_colors
mov text_color,al
ret
SHOW_COLORS: jmp display_color_help
;----------------------------------------------------------------
; CHECK_FILENAME: This checks if user want filenames displayed
;----------------------------------------------------------------
FILENAME_SWITCH db 0
CHECK_FILENAME: mov si,OFFSET switch_buffer
L1: lodsb
cmp al,0
je ret
cmp al,'/'
jne l1
lodsb
cmp al,'F'
jne l1
mov filename_switch,1
ret
;----------------------------------------------------------------
; READ_FILE1: This reads the user file specified on the command line
; If AUTOBOOT NOFILE or BLANK set NOPs in boot sector
;----------------------------------------------------------------
LENGTH dw ?
READ_FILE1: test W filename1
if z jmp help ;no file
; This checks for AUTOBOOT
mov si,filename1
mov di,OFFSET autoboot
mov cx,8
L1: cmpsb
jne >l2
loop l1
mov di,OFFSET boot_c ;NO PROMPT FOR C
mov ax,9090h ;NOP NOP
stosw
mov di,OFFSET skip_mesg ;NO MESSAGE DISPLAY
stosw ;NOP NOP
mov W signature,0
test B drive1
if z jmp help
ret
; This checks for NOFILE
l2: mov si,filename1
mov di,OFFSET nofile
mov cx,6
L3: cmpsb
jne >l4
loop l3
mov di,OFFSET skip_mesg ;NO MESSAGE DISPLAY
mov ax,9090h ;NOP NOP
stosw
mov W signature,0
test B drive1
if z jmp help
ret
; This checks for BLANK
l4: mov si,filename1
mov di,OFFSET blank
mov cx,5
L5: cmpsb
jne >l1
loop l5
mov di,COLOR_FILE_BUFFER
mov cx,2000
mov ah,text_color
mov al,20h
rep stosw
jmp >l0
; No AUTOBOOT, NOFILE, BLANK so we must have a filename
L1: mov dx,filename1 ;open
mov ax,3D00h
int 21h
jnc >l2
mov dx,OFFSET no_file_mesg
jmp error_message
L2: mov bx,ax ;get length
mov ax,4202h
mov cx,0
mov dx,0
int 21h
mov length,ax
jnc >l3
mov dx,OFFSET bad_size_mesg
jmp error_message
L3: cmp ax,4000 ;test length
je >l4
mov dx,OFFSET bad_size_mesg
jmp error_message
L4: mov ax,4200h ;rewind it
mov cx,0
mov dx,0
int 21h
mov ax,3F00h ;read file
mov cx,length
mov dx,COLOR_FILE_BUFFER
int 21h
jnc >l5
mov dx,OFFSET read_err_mesg
jmp error_message
L5: mov ah,3Eh ;close file
int 21h
; Now insert the prompt blanks on the color screen
L0: mov ah,0 ;put the prompt at /P
mov al,curpos
cmp al,24 ;0-24
ja >l3 ;off the screen
mov cl,al
xor dx,dx
mov bx,160 ;bytes per line
mul bx
mov di,ax ;is here
add di,COLOR_FILE_BUFFER
mov ax,0720h
cmp cl,24 ;remember 0-24
je >l2 ;just do one
cmp cl,23 ;two to do?
je >l1 ;yes
mov cx,30
rep stosw
add di,100
L1: mov cx,30
rep stosw
add di,100
L2: mov cx,30
rep stosw
L3: mov dx,OFFSET reading_mesg
call print_message
ret
;----------------------------------------------------------------
; READ_FILE2: This reads the SECOND file if specified
;----------------------------------------------------------------
GRID_NAME db 'GRID',0
READ_FILE2: test W filename2
jz ret ;there isn't one
; Test if he is requesting a grid
mov si,filename2
mov di,OFFSET grid_name
mov cx,4
L1: cmpsb
jne >l2
loop l1
jmp write_grid
L2: mov dx,filename2 ;open file
mov ax,3d00h
int 21h
jnc >l1
mov dx,OFFSET no_text_mesg
jmp error_message
L1: mov bx,ax ;get length
mov ax,4202h
mov cx,0
mov dx,0
int 21h
mov length,ax
jnc >l2
mov dx,OFFSET bad_size_mesg
jmp error_message
L2: cmp ax,2000 ;test for size
jbe >l3
mov dx,OFFSET bad_size_mesg2
jmp error_message
L3: mov ax,4200h ;rewind it
mov cx,0
mov dx,0
int 21h
mov ax,3F00h ;read file
mov cx,length
mov dx,TEXT_FILE_BUFFER
int 21h
jnc >l4
mov dx,OFFSET read_err_mesg
jmp error_message
L4: mov ah,3eh ;close file
int 21h
mov dx,OFFSET reading_mesg2
call print_message
jmp overlay_text
; Now lay it on top of the color message
LINE_NUMBER dw 0
BYTES_PER_LINE dw 160
PROMPT_FLAG db 0 ;this is set if writing
TEXT_COLOR db 07h ;set by /Cnn switch
CHAR_COUNT db 0 ;so we don't bust a line
WRITE_GRID: mov si,OFFSET grid ;lay down the grid
call overlay ;and come back for prompt
WRITE_PROMPT: mov ah,0 ;put the prompt
mov al,curpos ; according to /P
dec ax ;prompt starts with a cr
mov line_number,ax ;force it here
inc prompt_flag
mov si,OFFSET grid_prompt ;source
jmp overlay ;and return to main
OVERLAY_TEXT: mov si,TEXT_FILE_BUFFER
OVERLAY: mov di,COLOR_FILE_BUFFER
L1: lodsb ;get char from text buffer
cmp al,cr ;new line?
je >l3 ;yes
cmp al,lf ;ignore lf
je l1
cmp al,0 ;end of it?
je ret
cmp al,'_'
jne >l2
add di,2
jmp l1
L2: inc char_count
cmp char_count,80
ja l1
stosb ;save it
mov al,text_color ;make it /Cnn
test prompt_flag ;unless it's the prompt...
jz >l21
mov al,07h
L21: stosb
jmp l1 ;do more
L3: mov char_count,0
inc line_number ;new line
mov ax,line_number ;here
cmp ax,25 ;past end?
ja ret
mul bytes_per_line ;position of next line
mov di,ax ;is here
add di,COLOR_FILE_BUFFER
jmp l1 ;do more
ret
;----------------------------------------------------------------
; GET_TARGET: This puts the target drive in TARGET_DISK and IO NAMES
; Return if A: (default) or error if <> B:
;----------------------------------------------------------------
GET_TARGET: mov al,drive1 B
test al
if z jmp display_file
cmp al,'A'
je ret
cmp al,'B'
je >l1
mov dx,OFFSET bad_target_mesg
jmp error_message
L1: mov target_disk,1
mov ibm_sys,'B'
mov ms_sys,'B'
ret
;----------------------------------------------------------------
; CHECK_SYS: This checks if system is on the target disk by trying
; to open two files.
;----------------------------------------------------------------
CHECK_SYS: mov dx,OFFSET target_mesg
call print_message
mov dx,OFFSET ibm_sys ;check for ibmio.com
mov ax,3D00h
int 21h
jnc >l1
mov dx,OFFSET ms_sys ;check for io.sys
mov ax,3D00h
int 21h
jc ret
L1: mov dx,OFFSET system_mesg
jmp error_message
ret
;----------------------------------------------------------------
; GET_SIZE: This establishes the size of the target disk and the
; sector we will use for the color message
;----------------------------------------------------------------
GET_SIZE: mov dl,target_disk
inc dl
mov ah,36h
int 21h
mov bx,dx
xor dx,dx ;sec per cluster
mul cx ;times bytes per sec
cmp dx,0
jne size_error
mul bx ;number of clusters
add ax,dx ;ah=ax al=dx
cmp ax,3E16h ;ie 0016:3E00=1457664
je size_144
cmp ax,240Bh
je size_720
cmp ax,8805h
je size_360
cmp ax,8612h
je size_12
SIZE_ERROR: mov dx,OFFSET wrong_disk_mesg
jmp error_message
SIZE_144: mov dx,OFFSET size_144_mesg ;2870 already there
jmp >l1
SIZE_720: mov mesg_loc,1360
mov dx,OFFSET size_720_mesg
jmp >l1
SIZE_360: mov mesg_loc,710
mov dx,OFFSET size_360_mesg
jmp >l1
SIZE_12: mov mesg_loc,2390
mov dx,OFFSET size_12_mesg
L1: call print_message
ret
;----------------------------------------------------------------
; VERIFY: Sends a warning message if data .ne. F6h on target sector
; by doing an absolute read to the sector
;----------------------------------------------------------------
VERIFY: mov ax,signature W
cmp ax,0AAAAh
jne ret
mov al,target_disk
mov cx,1
mov dx,mesg_loc
mov bx,VERIFY_BUFFER
int 25h
pop bx ;stack garbage
jnc >l1
call seterrmsg
jmp init_error
L1: mov si,VERIFY_BUFFER
lodsw
cmp ax,0F6F6h
je ret
mov dx,OFFSET verify_mesg ;want to continue?
call print_message
L2: mov ah,8 ;wait for a key
int 21h
or al,20h
cmp al,'y'
je ret
cmp al,'n'
jne l2
mov dx,OFFSET abort_mesg
jmp error_message
;----------------------------------------------------------------
; WRITE_MESSAGE: This writes the message to the disk unless the
; signature has been zapped
;----------------------------------------------------------------
UNREG_MSG db ' '-64,'U'-64,'N'-64,'R'-64,'E'-64,'G'-64,'I'-64
db 'S'-64,'T'-64,'E'-64,'R'-64,'E'-64,'D'-64,' '-64
WRITE_MESSAGE:
; THIS WRITES AN UNREGISTERED MESSAGE
test register_byte
jnz >l2
mov di,OFFSET signature
add di,4000-26
mov ah,01Eh+80h
mov bx,OFFSET UNREG_MSG
mov cx,14
L1: mov al,[bx]
inc bx
add al,64
stosw
loop l1
L2: mov ax,signature W
cmp ax,0AAAAh
jne ret
mov al,target_disk
mov cx,8 ;8 sectors
mov dx,mesg_loc
mov bx,OFFSET signature
int 26h ;DOS Absolute Disk Write
pop bx ;stack shit
jnc ret ;done
call seterrmsg
jmp init_error
;--------------------------------------------------------------------
; WRITE_BOOT: - Installs our boot record on the target diskette
; Exit: CF - Set if error
; DX - OFFSET of error message if CF set
;--------------------------------------------------------------------
WRITE_BOOT: mov dx,OFFSET install_mesg
call print_message
; This writes a new jump at start of our boot sector (100h)
mov di,OFFSET entry
mov al,0E9h ;JMP short opcode
stosb
mov ax,OFFSET boot_1-OFFSET boot_data
stosw
; Read the boot sector from the target disk into a buffer
mov al,target_disk ;Get target disk
mov cx,1 ;read 1 sector
xor dx,dx ;Sector 0
mov si,dx
mov bx,TARGET_BOOT_SECTOR
call read_absolute
jc install_error
; This checks the JMP (short or long according to DOS version).
mov si,bx ;point to boot rec
lodsb ;get opcode
mov dl,al
lodsw ;get where to
mov bx,si ;next address
cmp dl,0EBh ;short JMP?
jne >l1 ;no
xor ah,ah ;if short JMP clear
jmp >l2 ; high byte
L1: cmp dl,0E9h ;Check for long JMP
je >l2
mov dx,OFFSET not_dos_mesg
jmp error_message
L2: mov dx,OFFSET cant_write_mesg
dec ax
cmp ax,OFFSET boot_dataend - OFFSET entry
if a jmp error_message
; This copies the boot data from target disk to our boot
mov si,bx
mov di,OFFSET boot_data ;copy boot data to
mov cx,ax ; boot rec
rep movsb
; This writes the boot sector to the target disk
mov al,target_disk ;Get target disk
mov bx,OFFSET entry
mov cx,1 ;1 sector
xor dx,dx ;Sector 0
xor si,si
call write_absolute ;Write new boot rec
jc install_error
ret
INSTALL_ERROR: call seterrmsg
INIT_ERROR: call print_msg
mov ax,4C01h
int 21h
;--------------------------------------------------------------------
; READ ABSOLUTE - Reads sectors from the disk.
; Entry: AL - Drive to read
; CX - Number of sectors to read.
; SI,DX - Sector to start read (SI only used on huge disks)
; DS:BX - Pointer to data buffer.
;--------------------------------------------------------------------
READ_ABSOLUTE: push bx
push cx
push ds
int 25h ;DOS Absolute Disk Read
pop bx ;stack shit
call seterrmsg
cld
pop ds
pop cx
pop bx
ret
;--------------------------------------------------------------------
; WRITE ABSOLUTE - Writes sectors to the disk.
; Entry: AL - Drive to write
; CX - Number of sectors to write
; SI,DX - Sector to start write (SI only used on huge disks)
; DS:BX - Pointer to data buffer.
;--------------------------------------------------------------------
WRITE_ABSOLUTE: push bx
push cx
push ds
int 26h ;DOS Absolute Disk Write
pop bx ;statck shit
call seterrmsg
cld
pop ds
pop cx
pop bx
ret
;----------------------------------------------------------------
; Sundry routines used by the above
;----------------------------------------------------------------
CAPS: cmp al,'a'
jb ret
cmp al,'z'
ja ret
and al,5Fh
ret
PRINT_MESSAGE: push ax
mov ah,9
int 21h
pop ax
ret
HELP: JMP DISPLAY_SCREEN
ERROR_MESSAGE: call print_message
mov ax,4C01h
int 21h
;----------------------------------------------------------------
; MESSAGE DATA
;----------------------------------------------------------------
NO_FILE_MESG db 'Color file not found',7,cr,lf,eom
NO_TEXT_MESG db 'Text file not found',7,cr,lf,eom
BAD_TARGET_MESG db 'Invalid target drive',7,cr,lf,eom
SYSTEM_MESG db 'Target contains system files. Aborted.',7,cr,lf,eom
TARGET_MESG db 'Verifying target disk',cr,lf,eom
WRONG_DISK_MESG db 'Wrong size disk',7,cr,lf,eom
VERIFY_MESG db 'WARNING! Message sector may contain data. Continue (Y/N)?',7,cr,lf,eom
ABORT_MESG db 'Aborted as user request',cr,lf,eom
SIZE_144_MESG db '1.44Mb disk detected',cr,lf,eom
SIZE_720_MESG db '720Kb disk detected',cr,lf,eom
SIZE_360_MESG db '360Kb disk detected',cr,lf,eom
SIZE_12_MESG db '1.2Mb disk detected',cr,lf,eom
READING_MESG db 'Reading color file',cr,lf,eom
READING_MESG2 db 'Reading text file',cr,lf,eom
BAD_SWITCH_MESG db 'Invalid switch',7,cr,lf,eom
BAD_CURPOS_MESG db 'Invalid cursor /P position',cr,lf,eom
BAD_TIMER_MESG db 'Invalid timer /T value',7,cr,lf,eom
TOO_LONG_MESG db 'Timer delay must not exceed 60 seconds',7,cr,lf,eom
BAD_COLOR_MESG db 'Invalid color /C specified',7,cr,lf,eom
NOT_DOS_MESG db 'Target diskette not a DOS formatted disk',7,cr,lf,eom
CANT_WRITE_MESG db 'Cannot write code on target disk',7,cr,lf,eom
INSTALL_MESG db 'Installing boot sector',cr,lf,eom
BAD_SIZE_MESG db 'Bad color file size (must be 4000 bytes)',7,cr,lf,eom
BAD_SIZE_MESG2 db 'Bad text file size (maximum 2000 bytes)',7,cr,lf,eom
READ_ERR_MESG db 'Error reading data file',7,cr,lf,eom
WRITE_ERROR db 'Error writing data to sector address',7,cr,lf,eom
DONE_MESSAGE db 'Disk modified OK',cr,lf,eom
HELLO db cr,lf
db 'COLRBOOT V1.0 ■ Release November 1994 JIM TUCKER',cr,lf
db 'Copyright (c) 1994 JIM TUCKER. All rights reserved',cr,lf,eom
;----------------------------------------------------------------
; This is the display stuff
;----------------------------------------------------------------
CURSOR_SIZE dw ?
CURSOR_POS dw ?
;----------------------------------------------------------------
; This moves the COLOR_HELP screen to the OUTPUT screen
;----------------------------------------------------------------
DISPLAY_COLOR_HELP:
mov si,OFFSET color_help
mov di,OFFSET output_screen
mov cx,2000
rep movsw
jmp display_screen
;----------------------------------------------------------------
; This moves the FILE (and any overlay) to the OUTPUT screen
;----------------------------------------------------------------
DISPLAY_FILE: call write_prompt ; put prompt on screen
mov si,COLOR_FILE_BUFFER ; get the file
mov di,OFFSET output_screen
mov cx,2000
rep movsw
test filename_switch ; /F switch?
jz display_screen ; no
mov si,filename1 ; display filename
mov di,OFFSET output_screen
add di,4000-40
mov ah,0Eh
L1: lodsb
test al
jz display_screen
stosw
jmp l1
;----------------------------------------------------------------
; Here to display the contents of the OUTPUT screen
;----------------------------------------------------------------
; This saves the current screen - we can overwrite the file buffer
; DS:SI is the screen, ES:DI is the buffer
DISPLAY_SCREEN: mov di,COLOR_FILE_BUFFER
mov ax,video_seg ; current video
mov ds, ax ; place in DS
xor si, si ; zero SI
mov cx, 2000
rep movsw ; store chars and color
mov ds,cs ; done, restore DS
; Save the cursor info
mov bh,0 ; page zero
mov ah,3 ; get cursor info
int 10h
mov cursor_pos,dx ; save it for restore
mov cursor_size,cx
; Hide the cursor
mov ah,2
mov bh,0
mov dx,1A00h
int 10h
test mono_switch
jz >l1
mov ah,0
mov al,7
int 10h
mov ax,video_seg
mov old_video_seg,ax
mov video_seg,0B000h
; This WRITES the OUTPUT screen to the VIDEO SEGMENT
L1: mov ax,video_seg
mov es,ax
mov si,offset OUTPUT_SCREEN
xor di,di
mov cx,2000
rep movsw
mov es,cs
L1: mov ah,01h ;wait for a keystroke
int 016h
jz l1
mov ah,0 ;clear keyboard buffer
int 016h
; Restore the screen
mov al,video_mode
mov ah,0
int 10h
mov ax,old_video_seg
mov video_seg,ax
; DS:SI is the buffer, ES:DI is the screen
L1: mov si,COLOR_FILE_BUFFER
mov ax,video_seg
mov es,ax
xor di,di
mov cx,2000
rep movsw
mov es,cs
; Put the cursor back
mov bh,0
mov dx,cursor_pos
mov ah,2
int 10h
mov cx,cursor_size
mov ah,1
int 10h
mov ax,4C00h
int 21h
;----------------------------------------------------------------
; The following are messages returned by absolute and read and write.
DOSERR_TBL dw OFFSET doserr_00
dw OFFSET doserr_01
dw OFFSET doserr_02
dw OFFSET doserr_03
dw OFFSET doserr_04
dw OFFSET doserr_05
dw OFFSET doserr_06
dw OFFSET doserr_07
dw OFFSET doserr_08
dw OFFSET doserr_09
dw OFFSET doserr_10
dw OFFSET doserr_11
dw OFFSET doserr_12
dw OFFSET doserr_unk
DOSERR_TBLEND = $
doserr_00 db "Disk Write Protected",0
doserr_01 db "Unknown Unit",0
doserr_02 db "Drive not ready",0
doserr_03 db "Unknown Command",0
doserr_04 db "CRC Data Error",0
doserr_05 db "Bad request structure",0
doserr_06 db "Disk Seek error",0
doserr_07 db "Not a DOS disk",0
doserr_08 db "Sector not found",0
doserr_09 db "Printer out of paper",0
doserr_10 db "Disk Write fault",0
doserr_11 db "Disk Read fault",0
doserr_12 db "General failure",0
doserr_unk db "Unknown DOS error",0
;--------------------------------------------------------------------
; SETERRMSG: Assigns a DOS error message to the value in AL
; Entry: AL - Error code
; CF - Set if error
; Exit: SI - Points to error message
;--------------------------------------------------------------------
SETERRMSG: push bx
pushf
jnc >l2
mov bx,ax
xor bh,bh
shl bx,1
cmp bx,OFFSET doserr_tblend - OFFSET doserr_tbl
jbe >l1
mov bx,26
L1: mov si,[bx+doserr_tbl]
L2: popf
pop bx
ret
;----------------------------------------------------------------
; PRINT_MSG: Prints ASCIIZ message to screen appending crlf
; Entry: DS:SI - Points to ASCIIZ message
;----------------------------------------------------------------
CRLF_MSG db 13,10,0
PRINT_MSG: call print_line
mov si,OFFSET crlf_msg
call print_line
ret
;----------------------------------------------------------------
; PRINT_LINE: Prints a line to the screen
; Entry: DS:SI - Points to ASCIIZ message
;----------------------------------------------------------------
PRINT_LINE: lodsb
or al,al
je >l1
mov dl,al
mov ah,02
int 21h
jmp short print_line
L1: ret
; If you do not have the latest version of A86 catenate these files
; to this file.
INCLUDE CMDLINE.A86
INCLUDE CBDATA.A86
; END COLRBOOT.A86